package core;

import static java.lang.System.out;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import com.trolltech.qt.core.QDir;
import com.trolltech.qt.core.QFileInfo;

/**
 * This is the main under the core package. This class supports the logic for
 * comparing two folders and finding the difference between the source folder
 * and the destination folder. All of the differences are noted in a log file
 * for convince.
 * 
 * 
 * 
 * 
 * @version 1.00 30 Mar 2010
 * @author Aviv Avitan
 */
public class FolderCompare {

	private void folderCompareHelper(QDir src, QDir dest, BufferedWriter bw)
			throws SecurityException, NoSuchMethodException, IOException {
		{
			List<QFileInfo> srcList = src.entryInfoList();
			List<QFileInfo> destList = dest.entryInfoList();
			List<String> destFileNames = dest.entryList();

			for (QFileInfo srcFile : srcList) {
				QFileInfoCompare srcFileC = new QFileInfoCompare(srcFile);

				out.print("Source file = " + srcFile.filePath() + "\n");

				if (srcFileC.fileName().equals(".")
						|| srcFileC.fileName().equals(".."))
					continue;

				// assuming same location indices for destFilesNames list and
				// destList (QFileInfo List) list.
				// The following should get the parallel file on the destination
				// folder.
				// TODO:: Should I sort the destFilesNames for improving
				// performance?
				int fileIndex = destFileNames.indexOf(srcFileC.fileName());

				if (fileIndex != -1) {
					QFileInfo parraelFileInfo = destList.get(fileIndex);

					out.println(parraelFileInfo.fileName());

					if (srcFileC.isDir())
						folderCompareHelper(new QDir(srcFileC.filePath()),
								new QDir(parraelFileInfo.filePath()), bw);
					else {
						out.println(srcFileC.fileName());
						out.println(parraelFileInfo.fileName());
						if (!srcFileC.equals(parraelFileInfo)) {
							folderError(srcFileC, bw, srcFileC.getErrors());
						}

					}
				} else {
					folderError(srcFileC, bw, "NOT_FOUND");
				}
			}
		}
	}

	/**
	 * This functions handles all abnormalities
	 * 
	 * @param srcFile
	 *            The folder/file where an error occurred while comparing
	 *            equality
	 * @param bw
	 *            A log object where we log the exceptions occurred in this
	 *            runtime.
	 * @param errors
	 *            A non-fixed length array of errors/differences between
	 *            source file and the compared (destination file).
	 * @throws IOException
	 *             If bw fails to log the exceptions, an IOExpcetion is
	 *             expected to be thrown.
	 */
	public void folderError(QFileInfo srcFile, BufferedWriter bw,
			String... errors) throws IOException {
		
		//TODO:: CALL FOR LOGIC to do some gui modifications
		String log = srcFile.filePath() + "\t";
		for (String error : errors) {
			log += error;
		}
		log += "\n";
		bw.write(log);

	}

	/**
	 * The main functions who iterates over the folders and files to check
	 * differences.
	 * 
	 * @param src
	 *            A QDir object representing the source folder which we
	 *            compare by it.
	 * @param dest
	 *            A QDir object representing the destination folder, which we
	 *            check if it contains all of the files and folders located in
	 *            the src folder.
	 * 
	 *            Assumptions: 1. Same files must have the same filename.
	 */
	public void folderCompare(QDir src, QDir dest) throws SecurityException,
			NoSuchMethodException, IOException {
		File outLog = new File("log.txt");

		FileWriter writer = new FileWriter(outLog);
		BufferedWriter bw = new BufferedWriter(writer);

		folderCompareHelper(src, dest, bw);
		bw.flush();
		bw.close();
		writer.close();

	}

	public static void main(String args[]) {
		QDir sourceFolder = new QDir(args[0]);
		QDir destFolder = new QDir(args[1]);

		FolderCompare core = new FolderCompare();

		System.out.print(sourceFolder.toString() + "\n");
		System.out.print(destFolder.toString() + "\n");

		try {
			core.folderCompare(sourceFolder, destFolder);
		} catch (SecurityException e) {

			e.printStackTrace();
		} catch (NoSuchMethodException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}

	}
}
